package com.wjc.train.business.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.wjc.train.business.entity.Admin;
import com.wjc.train.business.entity.SmsRecord;
import com.wjc.train.business.repository.AdminRepository;
import com.wjc.train.business.repository.SmsRecordRepository;
import com.wjc.train.business.req.AdminLoginReq;
import com.wjc.train.business.req.AdminSendCodeReq;
import com.wjc.train.business.service.IAdminService;
import com.wjc.train.business.service.ISmsService;
import com.wjc.train.common.enums.BusinessEnum;
import com.wjc.train.common.enums.LogicEnum;
import com.wjc.train.common.enums.SmsExpireEnum;
import com.wjc.train.common.exception.BusinessException;
import com.wjc.train.common.exception.BusinessExceptionCode;
import com.wjc.train.business.resp.AdminLoginResp;
import com.wjc.train.common.untils.CopyUtil;
import com.wjc.train.common.untils.JwtUtil;
import com.wjc.train.common.untils.LocalDateUtil;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Date;

/**
 * @author Guessed
 */
@Service
@Slf4j
public class AdminServiceImpl implements IAdminService {

    @Resource
    private AdminRepository adminRepository;

    @Resource
    private SmsRecordRepository smsRecordRepository;

    @Resource
    private ISmsService smsService;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public AdminLoginResp login(AdminLoginReq adminLoinReq){
        //校验手机号是否注册过
        Admin dBadmin = adminRepository.getBaseMapper().selectOne(new QueryWrapper<Admin>()
                .eq("mobile", adminLoinReq.getMobile()));
        //如果手机号不存在，则报错
        if(ObjectUtil.isEmpty(dBadmin)){
           throw new BusinessException(BusinessExceptionCode.USER_MOBILE_NOT_EXIST);
        }
        //校验短信验证码
        SmsRecord smsRecordDb = smsRecordRepository.getBaseMapper().selectOne(new QueryWrapper<SmsRecord>()
                .eq("mobile", adminLoinReq.getMobile())
                .eq("code", adminLoinReq.getCode())
                .eq("is_deleted", LogicEnum.NOT_DELETED.getCode())
                .isNull("use_time")
                .ge("expire_time", new Date()));

        if (ObjectUtil.isEmpty(smsRecordDb)){
            throw new BusinessException(BusinessExceptionCode.MEMBER_MOBILE_CODE_ERROR);
        }
        //设置使用时间,及删除状态
        smsRecordDb.setUseTime(new Date());
        smsRecordDb.setIsDeleted(LogicEnum.DELETED.getCode());
        smsRecordRepository.saveOrUpdate(smsRecordDb);

        AdminLoginResp adminLoginResp = CopyUtil.copy(dBadmin, AdminLoginResp.class);
        String token = JwtUtil.createToken(adminLoginResp.getId(), adminLoginResp.getMobile());
        adminLoginResp.setToken(token);
        return adminLoginResp;
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public void sendCode(AdminSendCodeReq adminSendCodeReq){

        String phoneNumber = adminSendCodeReq.getMobile();

        //校验手机号是否注册过
        Long count =
                adminRepository.lambdaQuery().eq(Admin::getMobile, phoneNumber).count();
        //如果手机号不存在，则报错
        if(count < 1){
            throw new BusinessException(BusinessExceptionCode.USER_MOBILE_NOT_EXIST);
        }
        //生成验证码,4位
        String codeKey = RandomUtil.randomNumbers(4);
        log.info("生成短信验证码: {}",codeKey);

        //存短信记录表
        //设置日期
        LocalDateTime localTime = LocalDateTime.now();
        LocalDateTime plus = localTime.plus(SmsExpireEnum.FIVE_MINUTES.getExpire(), ChronoUnit.MINUTES);
        Date sendTime = LocalDateUtil.localDateTimeToDate(localTime);
        Date expireTime = LocalDateUtil.localDateTimeToDate(plus);

        SmsRecord smsRecord = new SmsRecord();
        smsRecord.setMobile(phoneNumber);
        smsRecord.setSendTime(sendTime);
        smsRecord.setExpireTime(expireTime);
        smsRecord.setCode(codeKey);
        smsRecord.setBizType(BusinessEnum.ADMIN_LOGIN.getCode());
        smsRecordRepository.saveOrUpdate(smsRecord);

        //对接短信通道，发送短信
        smsService.sendCode(phoneNumber,codeKey);
    }

}
